package com.lcz.util;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;

/**
 * OSS 工具类
 *
 * @author lcz
 * @version 1.0
 * @date 2021/10/11 15:37
 */
@Component
public class UploadUtils {
    @Value("${qiniu.url}")
    private String url;
    @Value("${qiniu.accessKey}")
    private String accessKey;
    @Value("${qiniu.accessSecretKey}")
    private String accessSecretKey;
    @Value("${qiniu.bucketName}")
    private String bucket;
    @Value("${upload.type}")
    private String type;
    @Value("${smms.secretToken}")
    private String smmsSecretToken;
    @Value("${fdfs.web-server-url}")
    private String webServerUrl;

    @Autowired
    private FastFileStorageClient storageClient;

    /**
     * 上传图片
     *
     * @param file       文件
     * @param targetAddr 目标路径
     * @return OSS地址路径
     */
    public String upload(MultipartFile file, String targetAddr) {
        if ("qiniu".equals(type)) {
            return qiniuUpload(file, targetAddr);
        }
        if ("smms".equals(type)) {
            return smmsUpload(file);
        }
        if ("fastdfs".equals(type)) {
            return fastDFSUpload(file);
        }
        return null;
    }

    private String smmsUpload(MultipartFile multipartFile) {
        //MultipartFile转new File
        File file = new File(multipartFile.getOriginalFilename());
        try {
            FileCopyUtils.copy(multipartFile.getBytes(), file);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String result = HttpRequest.post("https://sm.ms/api/v2/upload")
                .header("Authorization", smmsSecretToken)
                .header("User-Agent", "Mozilla/5.0")
                .header("Content-Type", "application/x-www-form-urlencoded")
                .form("smfile", file)
                .timeout(20000)
                .execute().body();
        Map map = JSON.parseObject(result, Map.class);
        if ("true".equals(map.get("success"))) {
            JSONObject data = (JSONObject) map.get("data");
            return data.get("url").toString();
        } else {
            return map.get("images").toString();
        }
    }

    public String qiniuUpload(MultipartFile file, String targetAddr) {
        // 文件原始名
        String originalFilename = file.getOriginalFilename();
        // 不重复的新文件名
        String fileName = UUID.randomUUID() + "."
                + StringUtils.substringAfterLast(originalFilename, ".");
        // 获取文件存储的相对位置（带文件名）
        String relativeAddr = targetAddr + fileName;
        // 构造一个带指定 Region 对象的配置类
        Configuration cfg = new Configuration(Region.region2());
        // 其他参数参考类注释
        UploadManager uploadManager = new UploadManager(cfg);
        // 生成上传凭证，然后准备上传
//        String bucket = "lcz-blog";
        // 默认不指定key的情况下，以文件内容的hash值作为文件名
        try {
            byte[] uploadBytes = file.getBytes();
            Auth auth = Auth.create(accessKey, accessSecretKey);
            String upToken = auth.uploadToken(bucket);
            Response response = uploadManager.put(uploadBytes, relativeAddr, upToken);
            // 解析上传成功的结果
            DefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return url + relativeAddr;
    }

    public String fastDFSUpload(MultipartFile file) {
        try {
            // 获取扩展名
            String extension = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
            // 上传
            StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), extension, null);
            // 返回路径
            return webServerUrl + storePath.getFullPath();
        } catch (IOException e) {
            throw new RuntimeException("【文件上传】上传文件失败！" + e.getMessage());
        }
    }

}
